package com.danco.training.zaneuskaya.controller;


import java.io.Serializable;
import java.util.Date;

import com.danco.training.zaneuskaya.api.BookController;
import com.danco.training.zaneuskaya.api.BookService;
import com.danco.training.zaneuskaya.api.OrderController;
import com.danco.training.zaneuskaya.api.OrderService;
import com.danco.training.zaneuskaya.dependency.DependencyConfiguration;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.domain.Order;
import com.danco.training.zaneuskaya.view.IOUtil;





public class OrderControllerImpl implements Serializable, OrderController{
	

	private static final String READ_ORDER_LIST_FROM_FILE_MESSAGE = "Enter directory and file name to read order list ";
	private static final String SAVED_BY_DEFAULT_IN = "Saved by default in ";
	private static final String FILE_TO_SAVE_ORDER_LIST = "d:\\file1.csv";
	private static final String SAVE_ORDER_LIST_TO_FILE_MESSAGE = "Enter directory and file name for saving";
	private static final String COPY_ORDER_MESSAGE = "Enter order Id to copy";
	private static final String EXECUTE_ORDER_MESSAGE = "Enter order id to execute";
	private static final String BOOK_NOT_EXISTED = "Book not existed";
	private static final String ENTER_BOOK_ID_TO_DELETE = "Enter book id to delete";
	private static final String DELETE_BOOK_FROM_ORDER_MESSAGE = "Enter book id to delete from order";
	private static final String ADD_BOOK_TO_ORDER_MESSAGE = "Enter order id to add book";
	private static final String DELETE_ORDER_MESSAGE = "Enter order Id";
	private static final String CHANGE_ORDER_STATE_TRUE = "y";
	private static final String CHANGE_ORDER_STATE = "Change order state : y/n";
	private static final String UPDATE_ORDER_MESSAGE = "Enter order Id for modifying";
	private static final String ORDER_NOT_EXISTED_MESSAGE = "Order not existed";
	private static final String PRINT_ORDER_INFO_MESSAGE = "Enter order Id:";
	private static final String ENTER_BOOK_ID_TO_ADD_IN_ORDER = "Enter book Id to add:";
	private static final String CREATE_ORDER_MESSAGE = "Order creation";
	private static final String PRINT_EXECUTED_ORDER_LIST_SORTED_BY_PRICE = "Executed Orders in OrderStorage sorted by price ";
	private static final String PRINT_EXECUTED_ORDER_LIST_SORTED_BY_ORDER_DATE_MESSAGE = "Executed Orders in OrderStorage sorted by execution date ";
	private static final String ENTER_DATE_TO_FOR_ORDER_SORTING = "Enter date day to";
	private static final String ENTER_DATE_FROM_FOR_ORDER_SORTING = "Enter date from ";
	private static final String PRINT_NOT_EXECUTED_ORDERS_MESSAGE = "Not Executed Orders in OrderStorage ";
	private static final String PRINT_EXECUTED_ORDERS_MESSAGE = "Executed Orders in OrderStorage ";
	private static final String PRINT_ORDER_LIST_SORTED_BY_ORDER_DATE_MESSAGE = "Orders in OrderStorage sorted by execution date";
	private static final String PRINT_ORDER_LIST_MESSAGE = "Orders in OrderStorage";
	/**
	 * 
	 */
	private static final long serialVersionUID = -9033349643981321595L;
	private OrderService orderService = (OrderService) DependencyConfiguration.getInstanceByClassName(OrderService.class);
	private BookService bookService = (BookService) DependencyConfiguration.getInstanceByClassName(BookService.class);
	
	private BookController bookController = (BookController) DependencyConfiguration.getInstanceByClassName(BookController.class);

	public void printOrderList() {
		IOUtil.write(PRINT_ORDER_LIST_MESSAGE);
		for(Order order:orderService .getList()){
		IOUtil.write(orderInfo(order));
		}
		
	}

	public void printOrderListSortedByOrderDate() {
		IOUtil.write(PRINT_ORDER_LIST_SORTED_BY_ORDER_DATE_MESSAGE);
		for(Order order:orderService .sortOrdersByOrderDate(orderService .getList())){
			IOUtil.write(orderInfo(order));
			}
		
	}

	public void printExecutedOrders() {
		IOUtil.write(PRINT_EXECUTED_ORDERS_MESSAGE);
		for(Order order:orderService .getExecutedOrders(orderService .getList())){
			IOUtil.write(orderInfo(order));
			}
		

	}

	public void printNotExecutedOrders() {
		IOUtil.write(PRINT_NOT_EXECUTED_ORDERS_MESSAGE);
		for(Order order:orderService .getNotExecutedOrders(orderService .getList())){
			IOUtil.write(orderInfo(order));
			}
		
	}

	public void printExecutedOrderListSortedByOrderDate() {
		IOUtil.write(ENTER_DATE_FROM_FOR_ORDER_SORTING);
		
		Date d1 = IOUtil.readDate();
		IOUtil.write(ENTER_DATE_TO_FOR_ORDER_SORTING);
		
		Date d2 = IOUtil.readDate();
		IOUtil.write(PRINT_EXECUTED_ORDER_LIST_SORTED_BY_ORDER_DATE_MESSAGE);
		for(Order order:orderService .sortExecutedOrdersByOrderDate(orderService .getList(),d1,d2)){
			IOUtil.write(orderInfo(order));
			}
		

	}

	public void printExecutedOrderListSortedByPrice()  {
IOUtil.write(ENTER_DATE_FROM_FOR_ORDER_SORTING);
		
		Date d1 = IOUtil.readDate();
		IOUtil.write(ENTER_DATE_TO_FOR_ORDER_SORTING);
		
		Date d2 = IOUtil.readDate();
		IOUtil.write(PRINT_EXECUTED_ORDER_LIST_SORTED_BY_PRICE);
		for(Order order:orderService .sortExecutedOrdersByPrice(orderService .getList(),d1,d2)){
			IOUtil.write(orderInfo(order));
			}
	}

	public void createOrder(){
		IOUtil.write(CREATE_ORDER_MESSAGE);
		
		Order order = new Order(orderService .generateUnexistedId());
		orderService .addEntity(order);
		IOUtil.write(ENTER_BOOK_ID_TO_ADD_IN_ORDER);
		bookController.printBookList();
		int bookId = IOUtil.readInt();
		
		orderService .addBookToOrder(order,bookService.getById(bookId));

		IOUtil.write(orderInfo(order));
		

	}
	
	

	public void printOrderInfo() {
		IOUtil.write(PRINT_ORDER_INFO_MESSAGE);
		int id = IOUtil.readInt();
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(PRINT_ORDER_INFO_MESSAGE);
			id = IOUtil.readInt();
		}
		IOUtil.write(orderInfo(orderService .getById(id)));
	}
	
	
	public String orderInfo(Order i){
		StringBuffer str = new StringBuffer(i.getId() + "  ");
		for (Book book : i.getBooks()) {
			str.append(book.getId());
			str.append("  ");

		}
		str.append("   ");
		str.append(i.isExecuted()+ "  ");
		str.append(i.getTotalPrice());
		return str.toString();
	}

	public void updateOrder(){
		IOUtil.write(UPDATE_ORDER_MESSAGE);
		int id = IOUtil.readInt(); 
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(UPDATE_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}
		Order order = orderService .getById(id);
		
		IOUtil.write(CHANGE_ORDER_STATE);
		if (!IOUtil.read().equals(CHANGE_ORDER_STATE_TRUE) ){
			order.setExecuted(!order.isExecuted());
		}
		IOUtil.write(orderInfo(order));
		

	}

	public void deleteOrder() {
		IOUtil.write(DELETE_ORDER_MESSAGE);
		int id = IOUtil.readInt();
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(DELETE_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}
		orderService .removeEntityById(id);

	}

	public void addBookToOrder() {
		IOUtil.write(ADD_BOOK_TO_ORDER_MESSAGE);
		int id = IOUtil.readInt(); 
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(ADD_BOOK_TO_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}
		Order order = orderService .getById(id);
		
		IOUtil.write(ENTER_BOOK_ID_TO_ADD_IN_ORDER);
		bookController.printBookList();
		int bookId = IOUtil.readInt(); 
		while (bookService.getById(bookId)== null){
		
			IOUtil.write(ENTER_BOOK_ID_TO_ADD_IN_ORDER);
			
			bookId = IOUtil.readInt();
		}
		orderService .addBookToOrder(order, bookService.getById(bookId));

	}

	public void deleteBookFromOrder() {
		IOUtil.write(DELETE_BOOK_FROM_ORDER_MESSAGE);
		int id = IOUtil.readInt(); 
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(DELETE_BOOK_FROM_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}
		Order order = orderService .getById(id);
		
		IOUtil.write(ENTER_BOOK_ID_TO_DELETE);
		int bookId = IOUtil.readInt(); 
		while (bookService.getById(bookId)== null){
			IOUtil.write(BOOK_NOT_EXISTED);
			IOUtil.write(ENTER_BOOK_ID_TO_DELETE);
			
			bookId = IOUtil.readInt();
		}
		orderService .removeBookFromOrder(order, bookService.getById(bookId));
		IOUtil.write(orderInfo(order));

	}

	public void executeOrder() {
		IOUtil.write(EXECUTE_ORDER_MESSAGE);
		int id = IOUtil.readInt(); 
		while (orderService .getById(id)== null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(EXECUTE_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}
		orderService .executeOrderById(id);
	}

	public void copyOrder(){
		IOUtil.write(COPY_ORDER_MESSAGE);
		int id = IOUtil.readInt(); 
		
		while (orderService .getById(id) == null){
			IOUtil.write(ORDER_NOT_EXISTED_MESSAGE);
			IOUtil.write(COPY_ORDER_MESSAGE);
			id = IOUtil.readInt();
		}

		
			Order copy = null;
			try {
				copy = orderService .createOrderCopy(orderService .getById(id));
			} catch (CloneNotSupportedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		IOUtil.write(orderInfo(copy));
		
	}

	public void saveOrderListToFile()  {
		 IOUtil.write(SAVE_ORDER_LIST_TO_FILE_MESSAGE);
			String file = IOUtil.read();
			if (file.isEmpty()){
				file = FILE_TO_SAVE_ORDER_LIST;
				IOUtil.write(SAVED_BY_DEFAULT_IN + FILE_TO_SAVE_ORDER_LIST);
				
			}
			orderService .saveEntityListToFile(file);
				
	}
	
	public void readOrderListFromFile(){
		 IOUtil.write(READ_ORDER_LIST_FROM_FILE_MESSAGE);
			String file = IOUtil.read();
			if (file.isEmpty()){
				file = FILE_TO_SAVE_ORDER_LIST;
					
			}
			for (Order or: orderService .readEntityList(file)){
				orderService .addEntity(or);
			}
	}
	

	
}
